﻿using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace MP2
{
    public partial class MainForm : Form
    {
        Writer ISOWriter;
        XEXInfo XEXManager;
        File_Downloader FILEDownloader;

        private bool isResized;
        private bool ISO_PRESENT, SS_PRESENT, DMI_PRESENT;

        public MainForm()
        {
            InitializeComponent();

            pnlDragDrop.AllowDrop = true; //Logie's cheap ass poorboy bugfix.

            //Default position is open, so only do something for closed settings.
            if (Properties.Settings.Default.Panel_Closed == true)
            { closeOptionsTab(); }

            //Setup the Autpatch checkbox from the settings.
            if (Properties.Settings.Default.Autopatch == true)
            { chkAutopatch.Checked = true; }

            ISOWriter = new Writer();
            XEXManager = new XEXInfo();
            FILEDownloader = new File_Downloader();
        }

        #region Options Tab RESIZING Code
        /// <summary>
        /// Handles resizing of the Options Panel - The control that holds 'Autopatch' checkbox etc
        /// </summary>
        private void pbResizeArrow_Click(object sender, EventArgs e)
        {
            //Not yet resized, so we will resize the 'Options' panel smaller.
            if (isResized == false)
            {
                closeOptionsTab();
                return;
            }

            //Panel has already been resized, bring it back to original position.
            if (isResized == true)
            {
                openOptionsTab();
                return;
            }
        }

        /// <summary>
        /// Handles the closing of the Options panel.
        /// Saves bool of position to Settings.settings.
        /// </summary>
        private void closeOptionsTab()
        {
            Properties.Settings.Default.Panel_Closed = true;
            Properties.Settings.Default.Save();

            pnlOptions.Location = new Point(pnlOptions.Location.X + 100, pnlOptions.Location.Y);
            groupButtons.Location = new Point(groupButtons.Location.X + 25, groupButtons.Location.Y);
            groupCheckboxes.Location = new Point(groupCheckboxes.Location.X + 25, groupCheckboxes.Location.Y);
            pbResizeArrow.Image = Properties.Resources.mp2arrowResizeLeft;

            isResized = true;
        }

        /// <summary>
        /// Handles the opening of the Options panel.
        /// Also saves the opened bool to Settings.
        /// </summary>
        private void openOptionsTab()
        {
            Properties.Settings.Default.Panel_Closed = false;
            Properties.Settings.Default.Save();

            pnlOptions.Location = new Point(pnlOptions.Location.X - 100, pnlOptions.Location.Y);
            groupButtons.Location = new Point(groupButtons.Location.X - 25, groupButtons.Location.Y);
            groupCheckboxes.Location = new Point(groupCheckboxes.Location.X - 25, groupCheckboxes.Location.Y);
            pbResizeArrow.Image = Properties.Resources.mp2arrowResizeRight;

            isResized = false;
        }

        #endregion

        /// <summary>
        /// Handles the setting and saving of the Autopatch checkbox.
        /// </summary>
        private void chkAutopatch_CheckedChanged(object sender, EventArgs e)
        {
            if (chkAutopatch.Checked == true)
            { Properties.Settings.Default.Autopatch = true; }

            else
            { Properties.Settings.Default.Autopatch = false; }

            Properties.Settings.Default.Save();
        }

        /// <summary>
        /// Resets the form for use with Muliple ISOs.
        /// </summary>
        private void btnResetForm_Click(object sender, EventArgs e)
        { Application.Restart(); }

        private void pnlDragDrop_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                e.Effect = DragDropEffects.Move;
            else
                e.Effect = DragDropEffects.None;
        }

        private void pnlDragDrop_DragDrop(object sender, DragEventArgs e)
        {
            //DRAG N DROP EVENT HANDLER
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                //From the list of files dropped (if many), get the first.
                string[] FILELIST = (string[])e.Data.GetData(DataFormats.FileDrop);
                string FILE = FILELIST[0];

                FileInfo currentFile = new FileInfo(FILE);

                #region ISO File Dropped into Program
                //No ISO yet, and this file isn't either. So break operation.
                if (currentFile.Extension.ToLower() != ".iso" && ISO_PRESENT == false)
                {
                    MessageBox.Show("Mousepatcher requires an ISO before any other file!", "Mousepatcher 2.0");
                    return;
                }
                else if (currentFile.Extension.ToLower() == ".iso" && ISO_PRESENT == false)
                {
                    //If the Autopatch Checkbox is checked, and it's a valid ISO (Based off the success of the S32 Check)
                    //Go download the SS/DMI from the XEX CRC.
                    if (chkAutopatch.Checked == true && XEXManager.Sector32Check(FILE))
                    {
                        try
                        {
                            lblStatus.Text = "Autopatching ISO...";
                            //Parse Root Directory Sector for XEX Sector
                            XEXManager.RootDirectoryTable();
                            //Calculate CRC32 and return it.
                            string XEX_CRC32 = XEXManager.XEXInformation();
                            lblXEXCRC.Text = "XEX CRC: " + XEX_CRC32;

                            //If true, verify and write the files we've recieved. Else break operation.
                            if (FILEDownloader.DownloadSSFiles(XEX_CRC32))
                            {
                                //Validate the SS & DMI for integrity.
                                //If they pass, patch the ISO with 'em! :)
                                if (ISOWriter.CheckSS(FILEDownloader.SSLocation) && ISOWriter.CheckDMI(FILEDownloader.DMILocation))
                                {
                                    ISOWriter.CreateWriter(FILE);
                                    ISOWriter.SS_Writer(FILEDownloader.SSLocation, 0xFD8F800);
                                    ISOWriter.SS_Writer(FILEDownloader.DMILocation, 0xFD8F000);
                                    lblStatus.Text = "Finished Patching!";
                                }
                                else { lblStatus.Text = "Failed to Patch. Please try again."; }
                            }
                            else
                            {
                                //No SS returned. OH MY GOD PANIC ATTACK!!
                                lblStatus.Text = "Failed to find SS data for current ISO.";
                                return;
                            }
                        }
                        catch (Exception ex) { MessageBox.Show(ex.Message, "Mousepatcher 2.0"); }

                    }

                    // Create a filestream and check the ISO for basic validity.
                    // Not needed if above is passed, it must be valid for Sector 32 checks, XEX CRC etc.
                    else if (ISOWriter.CreateWriter(FILE) && ISOWriter.CheckISO(FILE))
                    {
                        lblStatus.Text = "Waiting for SS/DMI File";
                        ISO_PRESENT = true;
                    }
                }
                #endregion

                #region BIN File Dropped into Program
                if (currentFile.Extension.ToLower() == ".bin")
                {
                    //BIN file dropped. We've still got file(s) to patch.
                    //Figure out what it is.

                    //If this returns true, it's a Security Sector file, and we've not had one yet!
                    if (ISOWriter.CheckSS(FILE) && SS_PRESENT == false)
                    {
                        //Pass file to the SS/DMI writer with the offset of: 0xFD8F800.
                        ISOWriter.SS_Writer(FILE, 0xFD8F800);
                        SS_PRESENT = true;
                        if (DMI_PRESENT == false) { lblStatus.Text = "Waiting for DMI File"; }

                        //Show Confirmation in Status Label.
                        if (SS_PRESENT && DMI_PRESENT)
                        { lblStatus.Text = "Finished Patching!"; }
                        return;
                    }

                    //If this returns true, it's a DMI file, we've not had one yet!
                    if (ISOWriter.CheckDMI(FILE) && DMI_PRESENT == false)
                    {
                        //Pass file to the SS/DMI writer with the offset of: 0xFD8F000.
                        ISOWriter.SS_Writer(FILE, 0xFD8F000);
                        DMI_PRESENT = true;
                        if (SS_PRESENT == false) { lblStatus.Text = "Waiting for SS File"; }

                        //Show Confirmation in Status Label.
                        if (SS_PRESENT && DMI_PRESENT)
                        { 
                            lblStatus.Text = "Finished Patching!";
                            ISOWriter.ISOStream.Close();
                        }
                        return;
                    }
                #endregion
                }
            }
        }

        private void btnClrTmpData_Click(object sender, EventArgs e)
        {
            //Clear everything out of the %appdata% dir where I store the SS data.
            string mpDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Mousepatcher2.0");

            if(Directory.Exists(mpDir)) { Directory.Delete(mpDir, true); }
            MessageBox.Show("Removed all temporary data!", "Mousepatcher 2.0");
        }

        private void pbAbout_Click(object sender, EventArgs e)
        {
            AboutBox abBox = new AboutBox();
            abBox.ShowDialog();
        }
    }
}